# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.utils.safestring import mark_safe
from django.urls import reverse, NoReverseMatch
from django import template
from django.db import models
from xadmin import site as xadminSite
from haystack.utils import importlib
from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
register = template.Library()

RELATE_PREFIX = '_rel_'

@register.filter(name='search_include')
def search_include(value):
    try:
        if value:
            (app_label, object_name) = (value.object._meta.app_label, value.object._meta.object_name)
            template_name = "search/includes/%s/%s_fragment.html" % (app_label, object_name.lower())
            template.loader.get_template(template_name)
            return template_name
        else:
            return "search/includes/default_result_fragment.html"
    except template.TemplateDoesNotExist:
        return "search/includes/default_result_fragment.html"


@register.filter(name='display')
def search_display(value, arg):
    if not arg:
        return value
    if not isinstance(value, models.Model):
        return value
    fs = arg.split(",")
    texts = []
    for f in fs:
        if not hasattr(value, f):
            continue
        ft = value._meta.get_field(f)
        _label = ft.verbose_name
        if hasattr(ft, 'choices') and bool(ft.choices):
            _display = "get_%s_display" % f
            _value = getattr(value, _display)()
        else:
            _value = getattr(value, f)
        texts.append(u"<b>%s：</b>%s" % (_label, _value or ""))
    return mark_safe(u" ; ".join(texts))


@register.simple_tag
def model_highlight(query, value, arg):
    if not arg:
        return value
    if not isinstance(value, models.Model):
        return value
    # query_words = set([word.lower() for word in query.split() if not word.startswith('-')])
    # Handle a user-defined highlighting function.
    if hasattr(settings, 'HAYSTACK_CUSTOM_HIGHLIGHTER') and settings.HAYSTACK_CUSTOM_HIGHLIGHTER:
        # Do the import dance.
        try:
            path_bits = settings.HAYSTACK_CUSTOM_HIGHLIGHTER.split('.')
            highlighter_path, highlighter_classname = '.'.join(path_bits[:-1]), path_bits[-1]
            highlighter_module = importlib.import_module(highlighter_path)
            highlighter_class = getattr(highlighter_module, highlighter_classname)
        except (ImportError, AttributeError) as e:
            raise ImproperlyConfigured("The highlighter '%s' could not be imported: %s" % (settings.HAYSTACK_CUSTOM_HIGHLIGHTER, e))
    else:
        from haystack.utils.highlighting import Highlighter
        highlighter_class = Highlighter

    highlighter = highlighter_class(query)
    fs = arg.split(",")
    texts = []
    for f in fs:
        if not hasattr(value, f):
            continue
        ft = value._meta.get_field(f)
        _label = ft.verbose_name
        if hasattr(ft, 'choices') and bool(ft.choices):
            _display = "get_%s_display" % f
            _value = getattr(value, _display)()
        else:
            _value = getattr(value, f)
        if _value:
            highlighter.max_length = len(_value)
            _value = highlighter.highlight(_value)

        texts.append(u"<b>%s：</b>%s" % (_label, _value or ""))
    return mark_safe(u" ; ".join(texts))


@register.simple_tag
def related_links(obj):
    if not obj:
        return ""
    links = []
    fields = obj._meta.get_fields()
    _related_objects = [f for f in fields if (f.one_to_many or f.one_to_one) and f.auto_created and not f.concrete]
    links.append('<ul class="list-inline">')
    links.append('<li class="text-red">相关信息:<i class="fa fa-hand-o-right" aria-hidden="true"></i></li>')
    for r in _related_objects:
        if r.model not in xadminSite._registry.keys():
            continue
        # if not xadminSite.has_model_perm(r.model, 'view'):
        #     continue
        f = r.field
        label = r.related_model._meta.app_label
        model_name = r.related_model._meta.model_name
        rel_name = f.remote_field.get_related_field().name
        verbose_name = r.related_model._meta.verbose_name
        lookup_name = '%s%s__%s__exact' % (RELATE_PREFIX, f.name, rel_name)
        id = str(obj.pk)
        try:
            rel_url = reverse("xadmin:%s_%s_changelist" % (label, model_name))
        except NoReverseMatch:
            continue
        link = '<li><a href="%s?%s=%s" title="与当前结果相关的 %s">%s</a></li>' % (rel_url, lookup_name, id, verbose_name, verbose_name)
        links.append(link)
    links.append('</ul>')
    return mark_safe("".join(links))

